iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0

前言

延續上一篇(中篇),我們繼續製作 專屬的 Agent P

話不多說,我們正文開始,準備見證 Agent P 的誕生(。・∀・)ノ


實踐

請先確認上篇與中篇內容都有用出來喔!

Main

不了解 FastAPI 的 可以參考 Day 10Day 12,這裡就不再多說~
現在我們將之前撰寫好的 Root Agent 包裝成 API 端點:

load_dotenv()
app = FastAPI()

# CORS 設定
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


session_service = InMemorySessionService()
artifacts_service = InMemoryArtifactService()

class QueryRequest(BaseModel):
    query: str

@app.post("/query")
async def handle_query(request: QueryRequest):
    try:
        session = await session_service.create_session(
          state={},
          app_name="my_app",
          user_id="user"
          )
        
        parts = [types.Part(text=request.query)]
        content = types.Content(role="user",parts=parts)
        
        runner = Runner(
          app_name="my_app",
          agent=root_agent,
          session_service=session_service,
          artifact_service=artifacts_service
        )
        
        events_async = runner.run_async(
          session_id=session.id,
          user_id="user",
          new_message=content
        )
        
        response = []
        async for event in events_async:
          if event.content:
               for part in event.content.parts:
                    if part.text:
                         response.append(part.text)


        root_agent_response = "\n".join(response)
        return {
             "response": root_agent_response
          }
    
    except Exception as e:
        return {"error": str(e)}

Gradio

因為之前也有介紹過,這裡也不揚細說明~ 可以參考 Day 14
一個簡單的網頁互動介面:

import gradio as gr
import requests

# 向你的 FastAPI 發送對話請求
def multi_tool_chat(message, history):
    try:
        # 呼叫你的 FastAPI /query 端點
        url = "http://localhost:8080/query"
        
        payload = {
            "query": message
        }
        
        response = requests.post(url, json=payload, timeout=30)
        
        if response.status_code == 200:
            data = response.json()
            if "response" in data:
                return data["response"]
            elif "error" in data:
                return f"⚠️ 服務錯誤:{data['error']}\n\n別擔心,我們的技術團隊正在處理中。您可以稍後再試,或者先和我簡單聊聊天 😊"
            else:
                return "收到了回應,但格式有點特殊,讓我重新整理一下資訊給您 🤔"
        else:
            return f"🌐 連線問題 (HTTP {response.status_code})\n\n看起來網路有點不穩定,建議您稍後再試。期間如果想聊天,我隨時歡迎!"
            
    except requests.exceptions.Timeout:
        return "⏰ 查詢超時了\n\n網路可能比較慢,請稍等一下再試。如果持續有問題,可能是服務正在維護中 🔧"
        
    except requests.exceptions.ConnectionError:
        return """❌ 無法連接到服務

看起來 Agent P 的服務暫時離線了 😔

**您可以嘗試:**
1. 檢查 FastAPI 服務是否在運行 (http://localhost:8080)
2. 重新啟動服務後再試
3. 如果問題持續,可能需要檢查網路設定

**期間您也可以:**
- 直接使用手機查詢天氣
- 開啟 Spotify App 播放音樂
- 前往 HackMD 網站管理筆記
- 使用 Google 搜尋查詢資訊
- 或者就在這裡和我隨意聊聊 😊

我會持續嘗試重新連接服務!"""
        
    except Exception as e:
        return f"""😅 發生了意外錯誤

錯誤詳情:{str(e)}

別擔心,這些技術問題總是會解決的!
您可以:
1. 稍後重試
2. 重新整理頁面
3. 先在這裡隨意聊聊

我們的服務通常很穩定,可能只是暫時的小問題"""

# 建立最簡單的聊天介面  
demo = gr.ChatInterface(
    fn=multi_tool_chat,
    title="專屬助理 Agent P",
    description="""
    我是你的專屬助理 Agent P!
    
    **功能示範:**
        天氣查詢:「台北天氣如何」「東京現在幾點」
        音樂控制:「播放周杰倫」「建立播放清單」  
        筆記管理:「列出我的筆記」「建立新筆記」
        網路搜尋:「搜尋最新新聞」「查詢比特幣價格」
        日常對話:「你好」「謝謝」「我很累」
    
    即使遇到技術問題,我們也會用最溫暖的方式為您服務!
    """,
    examples=[
        "你好 P!",
        "台北天氣如何?",
        "播放一些輕音樂",
        "列出我的所有筆記", 
        "建立一個會議記錄筆記",
        "我的 HackMD 使用者資訊",
        "搜尋台積電最新新聞",
        "查詢比特幣價格",
        "找資料:人工智慧發展趨勢",
        "讀取網頁內容",
        "搜尋流行音樂",
        "建立一個放鬆音樂播放清單",
        "台中的溫度和濕度",
        "謝謝你的幫助"
    ],
    theme="soft"  # 使用溫暖的主題
)
                        
if __name__ == "__main__":
    print("🚀 啟動 P 的多功能助理服務...")
    print()
    print("📋 啟動前檢查清單:")
    print("   ✅ FastAPI 服務運行於 http://localhost:8080")
    print("   ✅ HackMD API Token 已設定")
    print("   ✅ Spotify 認證已完成")
    print("   ✅ SearXNG 服務運行於 http://localhost:8888")
    print("   ✅ MCP-SearXNG 服務運行於 http://localhost:5488")
    print("   ✅ 所有 MCP Server 可正常運作")
    print()
    print("🌐 Gradio 介面即將在瀏覽器中打開")
    print("💫 多功能助理團隊準備就緒,為您提供專業服務!")
    demo.launch()

實踐畫面

步驟 1:啟動 SearXNG 搜尋引擎 (Port 8888)

# 進入 Docker 目錄
cd ...\searxng-docker

# 檢查 docker-compose.yaml 是否存在
dir docker-compose.yaml

# 啟動 SearXNG 服務(背景運行)
docker compose up -d

# 驗證服務狀態
docker compose ps

步驟 2:啟動 MCP-SearXNG Server (Port 5488) - 可選

# 回到 mcp-searxng 目錄
cd ...\mcp-searxng or cd ..

# 啟動 MCP Server(如果你想使用 MCP 協議的話)
python server.py --searxng_url="http://localhost:8888"

步驟 3:啟動 Multi-Tool Agent 主服務 (Port 8080)

# 進入主專案目錄
# 確認虛擬環境已啟動
.venv\Scripts\activate

# 啟動 FastAPI 服務
uvicorn main:app --host 0.0.0.0 --port 8080

步驟 4:啟動 Gradio 使用者介面 (Port 7860)

# 開新終端,進入主專案目錄
# 啟動虛擬環境
.venv\Scripts\activate

# 啟動 Gradio 介面
python gradio_app.py

https://ithelp.ithome.com.tw/upload/images/20251013/20168454AuRmSQB83n.png
https://ithelp.ithome.com.tw/upload/images/20251013/20168454UCI71Y68Bk.png
https://ithelp.ithome.com.tw/upload/images/20251013/20168454JYDhRZifgh.png

# 關閉SearXNG 服務
docker compose down

結尾廢話

恭喜大家做出 Agent P~ (ノ◕ヮ◕)ノ*:・゚✧

大家可以依據自己的喜好去更改自己的 Prompt 等,做出符合自己需求,真正屬於自己的 Agent~

更多 Model Context Protocol servers可以自行搜尋、使用~

我們最後一篇見~ o(=•ェ•=)m
reference link


上一篇
[Day 28] 最後的專屬Agent P (中)
下一篇
[Day 30] Agent P 任務回憶錄
系列文
AI Agent 開發養成記:做出屬於自己的Agent P30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言